package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.Any("/*path", func(c *gin.Context) {
		// 获取请求基本信息
		url := c.Request.URL.String()
		method := c.Request.Method
		protocol := c.Request.Proto
		host := c.Request.Host
		path := c.Param("path")
		clientIP := c.ClientIP()
		timestamp := time.Now().Format("2006-01-02 15:04:05.000")
		requestID := fmt.Sprintf("%d", time.Now().UnixNano())

		// 获取 Cookies
		cookies := make(map[string]string)
		for _, cookie := range c.Request.Cookies() {
			cookies[cookie.Name] = cookie.Value
		}

		// 优化参数显示：单值显示为字符串，多值显示为数组
		params := make(map[string]interface{})
		for k, v := range c.Request.URL.Query() {
			if len(v) == 1 {
				params[k] = v[0]
			} else {
				params[k] = v
			}
		}

		// 获取请求头
		headers := make(map[string]string)
		for k, v := range c.Request.Header {
			headers[k] = strings.Join(v, ", ")
		}

		// 处理不同类型的请求体
		contentType := c.Request.Header.Get("Content-Type")
		var data interface{}
		var rawBody []byte

		if strings.Contains(contentType, "application/json") {
			// 处理JSON数据
			bodyBytes, err := io.ReadAll(c.Request.Body)
			if err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": "cannot read body"})
				return
			}
			rawBody = bodyBytes

			if err := json.Unmarshal(bodyBytes, &data); err != nil {
				// 如果JSON解析失败，保留原始字符串
				data = string(bodyBytes)
			}
		} else if strings.Contains(contentType, "multipart/form-data") {
			// 处理multipart/form-data
			err := c.Request.ParseMultipartForm(32 << 20) // 32 MB
			if err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"error": "cannot parse multipart form"})
				return
			}

			formData := make(map[string]interface{})
			for k, v := range c.Request.PostForm {
				if len(v) == 1 {
					formData[k] = v[0]
				} else {
					formData[k] = v
				}
			}

			if c.Request.MultipartForm != nil && c.Request.MultipartForm.File != nil {
				fileInfo := make(map[string]interface{})
				for field, fileHeaders := range c.Request.MultipartForm.File {
					files := make([]interface{}, 0)
					for _, fileHeader := range fileHeaders {
						file, err := fileHeader.Open()
						if err != nil {
							continue
						}
						defer file.Close()

						files = append(files, gin.H{
							"filename":    fileHeader.Filename,
							"size":        fileHeader.Size,
							"contentType": fileHeader.Header.Get("Content-Type"),
						})
					}
					// 单文件直接显示对象，多文件显示数组
					if len(files) == 1 {
						fileInfo[field] = files[0]
					} else {
						fileInfo[field] = files
					}
				}
				formData["_files"] = fileInfo
			}
			data = formData
		} else if strings.Contains(contentType, "application/x-www-form-urlencoded") {
			// 处理表单数据
			c.Request.ParseForm()
			formData := make(map[string]interface{})
			for k, v := range c.Request.PostForm {
				if len(v) == 1 {
					formData[k] = v[0]
				} else {
					formData[k] = v
				}
			}
			data = formData
		} else {
			// 处理其他类型的数据
			bodyBytes, err := io.ReadAll(c.Request.Body)
			if err == nil && len(bodyBytes) > 0 {
				rawBody = bodyBytes
				data = string(bodyBytes)
			}
		}

		// 获取服务器 hostname
		hostname, err := os.Hostname()
		if err != nil {
			hostname = "unknown"
		}

		// 构造响应对象
		response := gin.H{
			"request": gin.H{
				"id":        requestID,
				"timestamp": timestamp,
				"client": gin.H{
					"ip":   clientIP,
					"host": c.Request.RemoteAddr,
				},
				"method":   method,
				"protocol": protocol,
				"url":      url,
				"host":     host,
				"path":     path,
				"headers":  headers,
				"cookies":  cookies,
				"params":   params, // 使用优化后的参数
				"data":     data,
				"raw_body": string(rawBody),
			},
			"server": gin.H{
				"name":     "HTTP Request Debugger",
				"version":  "1.0.0",
				"hostname": hostname,
				"time":     time.Now().Format(time.RFC1123),
			},
		}

		// 返回JSON响应
		c.JSON(http.StatusOK, response)
	})

	// 启动服务
	fmt.Println("HTTP Request Debugger is running on port 7700")
	r.Run(":7700")
}
